﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;

namespace AutocompleteDemo
{
    [System.Runtime.InteropServices.Guid("CA7F9063-160C-472D-A684-FA60900F16C5")]
    public sealed class AutoCompletionService : SPIisWebService, IServiceAdministration
    {
        // Local singleton
        private static AutoCompletionService m_local = null;

        // An empty public constructor required for serialization.
        public AutoCompletionService()
        {;}

        public AutoCompletionService(SPFarm farm)
            : base(farm)
        { this.Name = "AutoCompletionService"; }

        // A static property that retrieves the content service.
        public static AutoCompletionService Local
        {
            get
            {
                if (AutoCompletionService.m_local == null)
                {
                    AutoCompletionService.m_local =
                      SPFarm.Local.Services.GetValue<AutoCompletionService>("AutoCompletionService");
                }

                return AutoCompletionService.m_local;
            }
        }

        public override SPAdministrationLink GetCreateApplicationLink(
            Type serviceApplicationType)
        {
            // NOTE: Since there can be only one instance of this service,
            // and there is only one application type, the target page 
            // does not require any querystring parameters.
            return new SPAdministrationLink("/_admin/AutocompleteDemo/ServiceCreate.aspx");
        }

        internal AutoCompletionServiceApplication GetWebApplicationByName(string applicationName)
        {
            ExceptionHelper.VerifyStringArgumentValid(applicationName, "applicationName", true);
            return base.Applications.GetValue<AutoCompletionServiceApplication>(applicationName);
        }

        #region IServiceAdministration

        public SPServiceApplication CreateApplication(string name, Type serviceApplicationType, SPServiceProvisioningContext provisioningContext)
        {
            throw new NotImplementedException();
        }

        private static AutoCompletionServiceApplication EnsureSettingsAttributesInitialization(AutoCompletionServiceApplication application)
        {
            if (application != null)
            {
                // application.InitAttributes();
            }
            return application;
        }

        public AutoCompletionServiceApplication CreateApplication(string name, bool checkIfExist, SPIisWebServiceApplicationPool applicationPool)
        {
            if (checkIfExist)
            {
                AutoCompletionServiceApplication webApplicationByName = this.GetWebApplicationByName(name);
                if (webApplicationByName != null)
                {
                    return webApplicationByName;
                }
            }
            if (applicationPool == null)
            {
                return new AutoCompletionServiceApplication(name, this);
            }
            return new AutoCompletionServiceApplication(name, this, applicationPool);
        }

        public SPServiceApplicationProxy CreateProxy(string name, SPServiceApplication serviceApplication, SPServiceProvisioningContext provisioningContext)
        {
            return this.CreateProxy(name, true, serviceApplication, provisioningContext);
        }

        public SPServiceApplicationProxy CreateProxy(string name, bool checkIfExist, SPServiceApplication serviceApplication, SPServiceProvisioningContext provisioningContext)
        {
            if (null == serviceApplication)
                throw new ArgumentNullException("serviceApplication");
            if (!ValidateType(serviceApplication.GetType()))
                throw new NotSupportedException();

            AutoCompletionServiceProxy serviceProxy = (AutoCompletionServiceProxy)base.Farm.GetObject(string.Empty, base.Farm.Id, typeof(AutoCompletionServiceProxy));
            if (serviceProxy == null)
            {
                serviceProxy = new AutoCompletionServiceProxy(base.Farm);
                serviceProxy.Update(true);
            }
            if (checkIfExist)
            {
                AutoCompletionServiceApplicationProxy proxy2 = serviceProxy.ApplicationProxies.GetValue<AutoCompletionServiceApplicationProxy>(name);
                if (proxy2 != null)
                {
                    return proxy2;
                }
            }

            return new AutoCompletionServiceApplicationProxy(name, serviceProxy, (AutoCompletionServiceApplication)serviceApplication);
        }

        public SPPersistedTypeDescription GetApplicationTypeDescription(
            Type serviceApplicationType)
        {
            if (serviceApplicationType != typeof(AutoCompletionServiceApplication))
            {
                throw new NotSupportedException();
            }

            return new SPPersistedTypeDescription(
                "Auto Completion Service Application",
                "Demonstration Auto Completion shared services.");
        }

        public Type[] GetApplicationTypes()
        {
            return new Type[] { typeof(AutoCompletionServiceApplication) };
        }

        #endregion

        private static bool ValidateType(Type type)
        {
            if ((type != null) && (type == typeof(AutoCompletionServiceApplication)))
            {
                return true;
            }
            return false;
        }

        internal AutoCompletionServiceApplication GetWebApplicationById(Guid applicationId)
        {
            return EnsureSettingsAttributesInitialization(base.Applications.GetValue<AutoCompletionServiceApplication>(applicationId));
        }

        internal List<AutoCompletionServiceApplication> GetApplications()
        {
            List<AutoCompletionServiceApplication> retval = new List<AutoCompletionServiceApplication>();

            foreach (AutoCompletionServiceApplication application in AutoCompletionService.Local.Applications)
            {
                try
                {
                    application.DemandAdministrationReadAccess();
                    retval.Add(application);
                    continue;
                }
                catch (System.Security.SecurityException)
                {
                    continue;
                }
            }

            return retval;
        }
    }
}
